<!DOCTYPE html>
<html lang="cn">
<head>
    <meta charset="utf-8"/>
    <title>WebRTC Example</title>
    <script src="./ws.js"></script>
    <script src="./vue.js"></script>
    <link rel="stylesheet" type="text/css" href="./client.css">
</head>
<body>
<div id="main">
    <h1>{{message}}</h1>
    <button @click="this.getAllClients">getAllClients</button>
    <table>
        <tr>
            <td>
                发送端
                <video width="200" height="200" id="localVideo" autoplay></video>
                <button id="callButton" @click="this.callRemote">呼叫</button>
            </td>
            <td>
                接收端
                <video width="200" height="200" id="remoteVideo" autoplay></video>
            </td>
        </tr>
    </table>

</div>

<script>

  let VueComp = new Vue({
    el: '#main',
    data() {
      return {
        message: 'WebRTC Example',
        streamA: null,
        peerA: null,
        peerB: null,
        wsA: null,
        wsB: null,
        localVideoElement: null,
        remoteVideoElement: null,
        callButton: null,
      }
    },
    mounted() {
      console.log('mounted')

      this.peerA = new RTCPeerConnection();
      this.peerB = new RTCPeerConnection();
      this.wsA = new WSS("ws://127.0.0.1:3001?sessionId=A");
      this.wsB = new WSS("ws://127.0.0.1:3001?sessionId=B");

      this.localVideoElement = document.querySelector('#localVideo');
      this.remoteVideoElement = document.querySelector('#remoteVideo');
      this.callButton = document.querySelector("#callButton");

      // 获取本地音视频数据并将其添加到 peer 中
      navigator.mediaDevices
        .getDisplayMedia({video: true})
        .then(stream => {
          // 将音视频设置到页面上
          this.localVideoElement.srcObject = stream
          this.streamA = stream;

        })

      this.peerB.ontrack = (event) => {
        console.log('获取视频流', event)
        this.remoteVideoElement.srcObject = event.streams[0]
      }

      this.setASubscribe()
      this.setBSubscribe()

    },
    methods: {
      getAllClients() {
        this.wsA.send({type: 'getAllClients'})
      },
      callRemote() {
        console.log('1 发起端点击call时创建offer并发送给接收端')
        // 将音视频添加到 peer 中
        this.streamA.getTracks().forEach((track) => this.peerA.addTrack(track, this.streamA));

        this.peerA.createOffer().then(async offer => {
          await this.peerA.setLocalDescription(offer)

          this.wsB.send({
            type: 'call',
            data: {
              sessionId: 'B', // 为了方便，这里写死
              sdp: offer.sdp
            }
          })
        })

        this.peerA.addEventListener('icecandidate', (event) => {
          var iceCandidate = event.candidate;
          console.log(`iceCandidate is ${JSON.stringify(iceCandidate)}`);
          if (iceCandidate) {
            // 同步补充描述信息给目的端（通过SDP协商结果进行信息交换），描述信息包括协议、IP、端口、优先级等等信息
            // 问题：为什么这些描述信息不可以放在信令中
            this.wsA.send({
              type: 'ice',
              data: {
                sessionId: 'B',
                iceCandidate
              }
            });
          }
        });


      },
      setASubscribe() {
        this.wsA.subscribe('getAllClients', e => {
          console.log('所有会话', e)
        })

        // 发起端收到answer sdp
        this.wsA.subscribe('answer', async (data) => {
          console.log('4 发起端收到answer sdp')
          const sdp = data.data
          await this.peerA.setRemoteDescription({
            type: 'answer',
            sdp
          })
        })

        this.wsA.subscribe('ice', async data => {
          console.log(`get ice message`);
          this.peerA.addIceCandidate(new RTCIceCandidate(data.data.iceCandidate));
        })
      },
      setBSubscribe() {
        // 接收端收到 offer sdp
        this.wsB.subscribe('call', async (data) => {
          console.log('2. 接收端收到发送端的 offer sdp', data)
          const sdp = data.data
          await this.peerB.setRemoteDescription({
            type: 'offer',
            sdp
          })

          // 接收端创建answer并发送给发起端
          this.peerB.createAnswer().then(async answer => {
            console.log('3 接收端创建answer并发送给发起端')
            await this.peerB.setLocalDescription(answer)
            this.wsB.send({
              type: 'answer',
              data: {
                sdp: answer.sdp,
                sessionId: 'A' // 为了方便，这里写死
              }
            })
          })

          this.peerB.addEventListener('icecandidate', (event) => {
            var iceCandidate = event.candidate;
            console.log(`iceCandidate is ${JSON.stringify(iceCandidate)}`);
            if (iceCandidate) {
              // 同步补充描述信息给目的端（通过SDP协商结果进行信息交换），描述信息包括协议、IP、端口、优先级等等信息
              // 问题：为什么这些描述信息不可以放在信令中
              this.wsA.send({
                type: 'ice',
                data: {
                  sessionId: 'A',
                  iceCandidate
                }
              });
            }
          });

        })

        this.wsB.subscribe('ice', async data => {
          console.log(`get ice message`);
          this.peerB.addIceCandidate(new RTCIceCandidate(data.data.iceCandidate));
        })


      }
    }
  })

</script>
</body>
</html>